package org.example;

import com.google.common.util.concurrent.*;

import java.util.Random;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;

/**
 *  可以看到异步方法的本质是: 开启一个新线程执行任务,开启一个新线程执行回调函数
 */
public class GuavaAsync {
    public static void main(String[] args) throws Exception{

        //首先通过MoreExecutors类的静态方法listeningDecorator方法初始化一个ListeningExecutorService的方法，
        // 然后使用此实例的submit方法即可初始化ListenableFuture对象。
        ListeningExecutorService listeningExecutorService = MoreExecutors.listeningDecorator(Executors.newCachedThreadPool());

        //任务线程池,执行长耗时方法
        final ListenableFuture<Long> listenableFuture = listeningExecutorService.submit(new Callable<Long>() {
            @Override
            public Long call() throws Exception {
                System.out.println("任务线程callable中call方法执行了-----线程名:" + Thread.currentThread().getName());
                Long _long = 0L;

                long start = System.currentTimeMillis();
                for (long i = 0; i <= 199_999_999L; i++) {
                    Random random = new Random();
                    int seed = random.nextInt(100);
                    Random random1 = new Random(seed);
                    int i1 = random1.nextInt(100);
                    _long = i1 + _long;
                }
                long end = System.currentTimeMillis();

                System.out.println("任务线程callable中程序耗时:" + (end - start) + "毫秒------运行的结果是:" +
                        _long + "---线程:" + Thread.currentThread().getName());

                //模拟任务执行失败，抛出异常
//                int i=1/0;

                return _long;
            }
        });

        //ListenableFuture要做的工作，在Callable接口的实现类中定义，
        // 可以执行此Future并执行Future完成之后的回调函数。

        ExecutorService singleThreadExecutor = Executors.newSingleThreadExecutor();

        Futures.addCallback(listenableFuture, new FutureCallback<Long>() {
            @Override
            public void onSuccess(Long result) {
                //成功执行...
                System.out.println("监控线程callback成功执行了,获取结果是:" + result + " ---线程名:" + Thread.currentThread().getName());
            }

            @Override
            public void onFailure(Throwable t) {
                System.out.println("监控线程callback出现异常了 ---线程名:" + Thread.currentThread().getName());
                //异常情况处理...
                t.printStackTrace();
            }
        }, singleThreadExecutor);

        System.out.println("主线程执行完成1");

//        while (true) {
//            if (executorService.isTerminated()) {
//                executorService.shutdown();
//                break;
//            }
//        }

        listeningExecutorService.awaitTermination(15, TimeUnit.SECONDS);
        listeningExecutorService.shutdown();
        System.out.println("主线程执行完成2");

//        while (true) {
//            if (singleThreadExecutor.isTerminated()) {
//                singleThreadExecutor.shutdown();
//                break;
//            }
//        }

        singleThreadExecutor.awaitTermination(5, TimeUnit.SECONDS);
        singleThreadExecutor.shutdown();
        System.out.println("主线程执行完成3");
    }
}
